package com.zhentao.config;

import com.zhentao.service.AiConversationService;
import com.zhentao.service.AiMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
@Slf4j
public class RedisChatMemory implements ChatMemory {
    private static final String REDIS_KEY_PREFIX = "chatmemory:";
    private static final int DEFAULT_TTL_HOURS = 24; // Redis缓存24小时过期

    private final RedisTemplate<String, Message> redisTemplate;

    @Autowired(required = false)
    private AiConversationService conversationService;

    @Autowired(required = false)
    private AiMessageService messageService;

    @Override
    public void add(String conversationId, Message message) {
        log.debug("添加单条消息到会话: {}", conversationId);

        String key = REDIS_KEY_PREFIX + conversationId;

        // 添加消息到Redis
        redisTemplate.opsForList().rightPush(key, message);

        // 设置过期时间
        redisTemplate.expire(key, DEFAULT_TTL_HOURS, TimeUnit.HOURS);

        // 异步保存到MongoDB（如果服务可用）
        saveMessageToDatabase(conversationId, message);
    }

    @Override
    public void add(String conversationId, List<Message> messages) {
        log.debug("添加多条消息到会话: {}, 消息数量: {}", conversationId, messages.size());

        String key = REDIS_KEY_PREFIX + conversationId;

        // 批量添加消息到Redis
        redisTemplate.opsForList().rightPushAll(key, messages);

        // 设置过期时间
        redisTemplate.expire(key, DEFAULT_TTL_HOURS, TimeUnit.HOURS);

        // 异步保存到MongoDB（如果服务可用）
        for (Message message : messages) {
            saveMessageToDatabase(conversationId, message);
        }
    }



    @Override
    public List<Message> get(String conversationId) {
        log.debug("获取会话消息: {}", conversationId);

        String key = REDIS_KEY_PREFIX + conversationId;

        // 首先尝试从Redis获取
        List<Message> messages = redisTemplate.opsForList().range(key, 0, -1);

        if (messages != null && !messages.isEmpty()) {
            log.debug("从Redis获取到 {} 条消息", messages.size());
            return messages;
        }

        // 如果Redis中没有，尝试从MongoDB加载最近的消息
        if (messageService != null) {
            try {
                log.debug("Redis中无消息，尝试从MongoDB加载");
                var recentMessages = messageService.getRecentMessages(conversationId, 50);

                if (!recentMessages.isEmpty()) {
                    // 将MongoDB中的消息转换为Spring AI的Message格式并缓存到Redis
                    List<Message> aiMessages = recentMessages.stream()
                        .map(this::convertToAiMessage)
                        .toList();

                    // 缓存到Redis
                    redisTemplate.opsForList().rightPushAll(key, aiMessages);
                    redisTemplate.expire(key, DEFAULT_TTL_HOURS, TimeUnit.HOURS);

                    log.debug("从MongoDB加载并缓存了 {} 条消息", aiMessages.size());
                    return aiMessages;
                }
            } catch (Exception e) {
                log.warn("从MongoDB加载消息失败: {}", e.getMessage());
            }
        }

        log.debug("未找到会话消息: {}", conversationId);
        return List.of();
    }

    @Override
    public void clear(String conversationId) {
        log.debug("清空会话消息: {}", conversationId);

        String key = REDIS_KEY_PREFIX + conversationId;
        redisTemplate.delete(key);
    }

    /**
     * 异步保存消息到MongoDB
     */
    private void saveMessageToDatabase(String conversationId, Message message) {
        if (messageService == null || conversationService == null) {
            return;
        }

        try {
            // 从会话ID中提取用户ID（这里需要根据实际的会话ID格式调整）
            Integer userId = extractUserIdFromConversationId(conversationId);
            if (userId == null) {
                log.warn("无法从会话ID中提取用户ID: {}", conversationId);
                return;
            }

            String content = message.getText();
            String messageType = determineMessageType(message);

            // 保存消息
            if ("USER".equals(messageType)) {
                messageService.saveUserMessage(userId, conversationId, content);
            } else if ("ASSISTANT".equals(messageType)) {
                messageService.saveAssistantMessage(userId, conversationId, content, "qwen-plus", null);
            }

            // 更新会话的最后消息信息
            conversationService.updateLastMessage(conversationId, content);

        } catch (Exception e) {
            log.error("保存消息到数据库失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 从会话ID中提取用户ID
     * 假设会话ID格式为: ai_{timestamp}_{uuid} 或包含用户信息
     */
    private Integer extractUserIdFromConversationId(String conversationId) {
        // 这里需要根据实际的会话ID生成规则来实现
        // 暂时返回null，需要在实际使用时根据业务逻辑调整
        try {
            // 如果会话ID中包含用户ID信息，可以在这里解析
            // 例如: user_{userId}_ai_{timestamp}
            if (conversationId.contains("user_")) {
                String[] parts = conversationId.split("_");
                if (parts.length > 1) {
                    return Integer.parseInt(parts[1]);
                }
            }
        } catch (Exception e) {
            log.warn("解析会话ID中的用户ID失败: {}", conversationId);
        }
        return null;
    }

    /**
     * 确定消息类型
     */
    private String determineMessageType(Message message) {
        if (message instanceof UserMessage) {
            return "USER";
        } else if (message instanceof AssistantMessage) {
            return "ASSISTANT";
        }
        return "SYSTEM";
    }

    /**
     * 将数据库消息转换为Spring AI消息格式
     */
    private Message convertToAiMessage(com.zhentao.dto.AiMessageDTO messageDTO) {
        if (messageDTO.isUserMessage()) {
            return new UserMessage(messageDTO.getContent());
        } else if (messageDTO.isAssistantMessage()) {
            return new AssistantMessage(messageDTO.getContent());
        } else {
            // 系统消息或其他类型
            return new UserMessage(messageDTO.getContent());
        }
    }

    /**
     * 获取会话的消息数量
     */
    public long getMessageCount(String conversationId) {
        String key = REDIS_KEY_PREFIX + conversationId;
        Long count = redisTemplate.opsForList().size(key);
        return count != null ? count : 0;
    }

    /**
     * 限制会话消息数量（保留最新的N条消息）
     */
    public void limitMessages(String conversationId, int maxMessages) {
        String key = REDIS_KEY_PREFIX + conversationId;
        Long currentSize = redisTemplate.opsForList().size(key);

        if (currentSize != null && currentSize > maxMessages) {
            // 删除旧消息，保留最新的maxMessages条
            long toRemove = currentSize - maxMessages;
            for (int i = 0; i < toRemove; i++) {
                redisTemplate.opsForList().leftPop(key);
            }
            log.debug("会话 {} 消息数量限制为 {}, 删除了 {} 条旧消息", conversationId, maxMessages, toRemove);
        }
    }

}
